package com.baijiaoxi.common.model.base.service.extension;

import com.baijiaoxi.common.model.base.CommonError;
import com.baijiaoxi.common.model.base.CoreException;
import com.baijiaoxi.common.utils.jdk.BaseTypeParser;

import java.lang.reflect.Field;
import java.util.Date;

public class FieldGetByNameUtil {
    /**
     * 通过属性名获取对象属性值
     *
     * @param fieldName
     * @return
     */
    public static Long getFieldValueAsLong(Object entity, String fieldName, Long nullDefaultValue) {
        return BaseTypeParser.parseToLong(getFieldValue(entity, fieldName), nullDefaultValue);
    }

    public static Long getFieldValueAsLong(Object entity, String fieldName) {
        return getFieldValueAsLong(entity, fieldName, null);
    }

    public static Integer getFieldValueAsInteger(Object entity, String fieldName, Integer nullDefaultValue) {
        return BaseTypeParser.parseToInteger(getFieldValue(entity, fieldName), nullDefaultValue);
    }

    public static Integer getFieldValueAsInteger(Object entity, String fieldName) {
        return getFieldValueAsInteger(entity, fieldName, null);
    }

    public static String getFieldValueAsString(Object entity, String fieldName, String nullDefaultValue) {
        return BaseTypeParser.parseToString(getFieldValue(entity, fieldName), nullDefaultValue);
    }

    public static String getFieldValueAsString(Object entity, String fieldName) {
        Object value = getFieldValue(entity, fieldName);
        return value == null ? null : (String) value;
    }

    public static Date getFieldValueAsDate(Object entity, String fieldName) {
        Object value = getFieldValue(entity, fieldName);
        return value == null ? null : (Date) value;
    }

    public static Object getFieldValue(Object entity, String fieldName) {
        if (fieldName == null || fieldName.isEmpty())
            return null;
        if (fieldName.contains(".")) {
            String[] fields = fieldName.split("\\.");
            Object object = entity;
            for (String field : fields) {
                Object value = getFieldValue(object, object.getClass(), field);
                object = value;
                if (value == null)
                    break;
            }
            return object;
        } else
            return getFieldValue(entity, entity.getClass(), fieldName);
    }

    private static Object getFieldValue(Object entity, Class clazz, String fieldName) {
        if (fieldName == null || fieldName.isEmpty())
            return null;
        if (clazz.getName().equals("java.lang.Object"))
            throw CoreException.create(CommonError.noSuchField, entity, fieldName);
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);
        } catch (Exception e) {
            return getFieldValue(entity, clazz.getSuperclass(), fieldName);
        }
        field.setAccessible(true);
        try {
            return field.get(entity);
        } catch (Exception e) {
            throw CoreException.create(CommonError.noSuchField, entity, fieldName);
        }
    }
}
